水無瀬の部屋 > Programming > sample > tools > workthrd > workthrd.cpp |
---|
1: //*********************************************************
2: // プロジェクト: attrchng - Attributes Changer
3: // ファイル名: workthrd.cpp
4: //*********************************************************
5: #define USE_GETWORKERTHREADCANCELEVENTHANDLE // [unsafe]
6: #include <workthrd/workthrd.h>
7: #include <header/tooldbg.h> // VALID_TEST(), ASSERT(),
8: #include <header/toolbase.h> //
9: #include <header/toolsys.h>
10:
11:
12: //---------------------------------------------------------
13: // 定数型マクロ の 定義
14: //---------------------------------------------------------
15: #define DBG_ALLOCNAME "CreateWorkerThread"
16:
17:
18: //---------------------------------------------------------
19: // 構造体 の 宣言
20: //---------------------------------------------------------
21: typedef struct thread_tag
22: {
23: size_t magic;
24: HANDLE handle; // スレッドへのハンドル
25: HANDLE heventCancel; // 中断用イベント
26: WorkerThreadProc_t proc; //
27: void *param; //
28: } thread_t;
29:
30:
31: //---------------------------------------------------------
32: // ファイルスコープ関数 の 宣言
33: //---------------------------------------------------------
34: static bool FinishWorkerThread( thread_t *thread );
35: static DWORD WINAPI WorkerThreadProc( void *param );
36:
37:
38: //*********************************************************
39: // CreateWorkerThread
40: // サスペンド状態のスレッドを返すので、
41: // 作業を開始するには ResumeWorkerThread() を使う。
42: //*********************************************************
43: thread_t *
44: CreateWorkerThread
45: (
46: WorkerThreadProc_t proc,
47: void *param
48: )
49: {
50: // パラメタの仮定
51: ASSERT( IsValidCodePtr( proc ) );
52:
53: //
54: thread_t *thread = (thread_t *)malloc( sizeof( *thread ) );
55: if ( ! thread )
56: {
57: return null;
58: }
59:
60: //
61: thread->heventCancel = CreateEvent( null, true, false, null );
62: if ( ! thread->heventCancel )
63: {
64: free( thread );
65: return null;
66: }
67:
68: //
69: thread->magic = sizeof( *thread ); //
70: thread->proc = proc; //
71: thread->param = param; //
72:
73: // スレッドの作成
74: DWORD dwID;
75: thread->handle = BeginThreadEx
76: (
77: null,
78: 0,
79: WorkerThreadProc,
80: thread,
81: CREATE_SUSPENDED,
82: &dwID
83: );
84: if ( ! thread->handle )
85: {
86: VERIFY( CloseHandle( thread->heventCancel ) );
87: free( thread );
88: return null;
89: }
90: ASSERT( IsValidWorkerThread( thread ) );
91:
92: //
93: DBG_LOCK_ALLOCED_MEMORY( thread, DBG_ALLOCNAME ); // [DBG]
94: return thread;
95: }//CreateWorkerThread
96:
97: //*********************************************************
98: // DestroyWorkerThread
99: //*********************************************************
100: bool
101: DestroyWorkerThread
102: (
103: thread_t *thread
104: )
105: {
106: // パラメタの仮定
107: ASSERT( IsValidWorkerThread( thread ) );
108:
109: // 終了を要求して終了するまで待つ
110: FinishWorkerThread( thread );
111: ResumeWorkerThread( thread );
112: ASSERT( IsValidWorkerThread( thread ) );
113:
114: // 削除する
115: VERIFY( CloseHandle( thread->heventCancel ) );
116: thread->heventCancel = null;
117:
118: // 削除する
119: VERIFY( CloseHandle( thread->handle ) );
120: thread->handle = null;
121:
122: //
123: DBG_UNLOCK_ALLOCED_MEMORY( thread, DBG_ALLOCNAME ); // [DBG]
124: free( thread );
125:
126: return true;
127: }//DestroyWorkerThread
128:
129: //*********************************************************
130: // IsValidWorkerThread
131: //*********************************************************
132: bool
133: IsValidWorkerThread
134: (
135: const thread_t *thread
136: )
137: {
138: VALID_TEST( IsValidReadPtr( thread, sizeof( *thread ) ) );
139: VALID_TEST( sizeof( *thread ) == thread->magic );
140: VALID_TEST( thread->handle );
141: VALID_TEST( thread->heventCancel );
142: VALID_TEST( IsValidCodePtr( thread->proc ) );
143:
144: return true;
145: }//IsValidWorkerThread
146:
147: //*********************************************************
148: // GetWorkerThreadCancelEventHandle
149: //*********************************************************
150: HANDLE
151: GetWorkerThreadCancelEventHandle
152: (
153: const thread_t *thread
154: )
155: {
156: // パラメタの仮定
157: ASSERT( IsValidWorkerThread( thread ) );
158:
159: return thread->heventCancel;
160: }//GetWorkerThreadCancelEventHandle
161:
162: //*********************************************************
163: // ResumeWorkerThread
164: //*********************************************************
165: bool
166: ResumeWorkerThread
167: (
168: thread_t *thread
169: )
170: {
171: // パラメタの仮定
172: ASSERT( IsValidWorkerThread( thread ) );
173:
174: return ((DWORD)(-1)) != ResumeThread( thread->handle );
175: }//ResumeWorkerThread
176:
177: //*********************************************************
178: // CancelWorkerThread
179: //*********************************************************
180: bool
181: CancelWorkerThread
182: (
183: thread_t *thread
184: )
185: {
186: // パラメタの仮定
187: ASSERT( IsValidWorkerThread( thread ) );
188:
189: // キャンセル機能なし
190: if ( ! thread->heventCancel )
191: {
192: return false;
193: }
194:
195: // キャンセルを試みる
196: const bool result = !! SetEvent( thread->heventCancel );
197:
198: // キャンセルを認識できるようスレッドを起こす
199: ResumeWorkerThread( thread );
200:
201: // キャンセルを試みる
202: return result;
203: }//CancelWorkerThread
204:
205: //*********************************************************
206: // IsWorkerThreadFinished
207: //*********************************************************
208: bool
209: IsWorkerThreadFinished
210: (
211: const thread_t *thread
212: )
213: {
214: // パラメタの仮定
215: ASSERT( IsValidWorkerThread( thread ) );
216:
217: return IsSignalObject( thread->handle );
218: }//IsWorkerThreadFinished
219:
220: //*********************************************************
221: // IsWorkerThreadCanceled
222: //*********************************************************
223: bool
224: IsWorkerThreadCanceled
225: (
226: const thread_t *thread
227: )
228: {
229: // パラメタの仮定
230: ASSERT( IsValidWorkerThread( thread ) );
231:
232: return IsSignalObject( thread->heventCancel );
233: }//IsWorkerThreadCanceled
234:
235: //*********************************************************
236: // WaitWorkerThreadSignal
237: //*********************************************************
238: bool
239: WaitWorkerThreadSignal
240: (
241: const thread_t *thread
242: )
243: {
244: // パラメタの仮定
245: ASSERT( IsValidWorkerThread( thread ) );
246:
247: return WAIT_OBJECT_0 == WaitForSingleObject( thread->handle, INFINITE );
248: }//WaitWorkerThreadSignal
249:
250:
251: //******************************************************************************************************************
252: // private
253: //******************************************************************************************************************
254: //*********************************************************
255: // FinishWorkerThread
256: //*********************************************************
257: static
258: bool
259: FinishWorkerThread
260: (
261: thread_t *thread
262: )
263: {
264: // パラメタの仮定
265: ASSERT( IsValidWorkerThread( thread ) );
266:
267: if ( ! IsWorkerThreadFinished( thread ) )
268: {
269: // 終了を要求
270: CancelWorkerThread( thread );
271:
272: // 終了できるようスレッドを起こす
273: ResumeWorkerThread( thread );
274:
275: // 終了するまで待つ
276: WaitForSingleObject( thread->handle, INFINITE );
277: }
278:
279: return true;
280: }//FinishWorkerThread
281:
282:
283: //******************************************************************************************************************
284: // private - callback
285: //******************************************************************************************************************
286: //*********************************************************
287: // WorkerThreadProc
288: //*********************************************************
289: static
290: DWORD // スレッドの終了コード
291: WINAPI
292: WorkerThreadProc
293: (
294: void *param
295: )
296: {
297: // パラメタの仮定
298: ASSERT( IsValidWorkerThread( (thread_t *)param ) );
299:
300: thread_t *thread = static_cast<thread_t *>( param );
301: return thread->proc( thread, thread->param );
302: }//WorkerThreadProc
303:
304:
305: //** end **
参照:
水無瀬の部屋 > sample > tools > workthrd > workthrd.cpp |
---|
このページは cpp2web が出力しました。
水無瀬 優 postmaster@katsura-kotonoha.sakura.ne.jp
http://katsura-kotonoha.sakura.ne.jp/prog/code/tools/workthrd/workthrd_cpp.shtml